package mathsys2;

import java.util.Objects;

/**
 * 加法算式子类：继承AbstractArithmetic抽象类，实现加法特有的逻辑
 * 核心职责：
 * 1. 实现加法结果计算（num1 + num2），并校验和≤100（实验约束）；
 * 2. 实现加法交换律去重（a+b与b+a视为重复）；
 * 3. 重写hashCode()确保与equals()逻辑一致，支持集合去重。
 */
public class AdditionArithmetic extends AbstractArithmetic {

    /**
     * 构造方法：调用父类构造完成共性校验，限定运算符为'+'
     * @param num1 第一个运算数（0-100，实验约束）
     * @param num2 第二个运算数（0-100，实验约束）
     * @throws IllegalArgumentException 当加法和>100或参数违反父类约束时抛出
     */
    public AdditionArithmetic(int num1, int num2) {
        // 调用父类构造：父类自动校验num1/num2在0-100，且operator为'+'
        super(num1, num2, '+');
    }


    // -------------------------- 实现父类抽象方法：加法结果计算 --------------------------
    /**
     * 计算加法结果，并校验和≤100（实验“加法和不超过100”约束）
     * 若和>100，抛出异常；否则赋值给父类的protected属性result
     */
    @Override
    public void calculate() {
        int sum = getNum1() + getNum2();
        // 校验加法和≤100（父类未处理该约束，子类补充加法特有校验）
        if (sum > 100) {
            throw new IllegalArgumentException("加法结果超过100（实验约束）：" + getNum1() + "+" + getNum2() + "=" + sum);
        }
        // 赋值结果到父类的result属性（protected修饰，子类可直接访问）
        this.result = sum;
    }


    // -------------------------- 实现父类抽象方法：加法交换律去重 --------------------------
    /**
     * 判断两个加法算式是否重复（a+b与b+a视为重复，实验“无重复习题”需求）
     * @param obj 待比较的对象
     * @return true=重复，false=不重复
     */
    @Override
    public boolean equals(Object obj) {
        // 1. 引用相同：直接返回true
        if (this == obj) {
            return true;
        }
        // 2. 对象为null或类型不同：返回false（确保仅与加法子类比较）
        if (obj == null || getClass() != obj.getClass()) {
            return false;
        }
        // 3. 类型转换：转为加法子类实例
        AdditionArithmetic other = (AdditionArithmetic) obj;
        // 4. 交换律判定：(num1==other.num1且num2==other.num2) 或 (num1==other.num2且num2==other.num1)
        return (getNum1() == other.getNum1() && getNum2() == other.getNum2())
                || (getNum1() == other.getNum2() && getNum2() == other.getNum1());
    }


    // -------------------------- 重写hashCode()：确保与equals()逻辑一致 --------------------------
    /**
     * 按“小数+大数”计算哈希值（确保a+b与b+a的hashCode相同，支持集合去重）
     * 实验用途：配合HashSet等集合存储时，避免交换律重复的算式被误判为不同对象
     * @return 加法算式的哈希值
     */
    @Override
    public int hashCode() {
        // 取两个运算数的最小值和最大值，确保a+b与b+a的哈希值相同
        int minNum = Math.min(getNum1(), getNum2());
        int maxNum = Math.max(getNum1(), getNum2());
        // 结合运算符'+'计算哈希，确保与减法算式区分
        return Objects.hash(minNum, maxNum, getOperator());
    }
}